package server.logger;

import server.Lifecycle;
import server.LifecycleException;
import server.LifecycleListener;
import server.util.LifecycleSupport;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Timestamp;
/*
文件日志记录器,将信息打印文件
*/
/*
2023/2/8 该类内容全部写完,后续直接使用,无需修改
by cyl
 */
public class FileLogger extends LoggerBase implements Lifecycle {
    protected static final String info = "server.logger.FileLogger/1.0";

    //日志文件名的前缀
    private String prefix = "server.";
    //当前writer写的文件名上的日期
    private String date = "";
    //日志文件名的后缀
    private String suffix = ".log";
    //打印日志时是否打印时间
    private boolean timestamp = false;
    //打印日志的writer
    private PrintWriter writer = null;

    protected LifecycleSupport lifecycle = new LifecycleSupport(this);
    //是否启动
    private boolean started = false;
    //存放日志文件的目录
    private String directory = "logs";

    //getter-------------------------------------------------------------------------
    public String getDirectory() {
        return directory;
    }
    public String getPrefix() {
        return prefix;
    }
    public String getSuffix() {
        return suffix;
    }
    public boolean getTimestamp() {
        return timestamp;
    }
    //setter-------------------------------------------------------------------------
    public void setDirectory(String directory) {
        this.directory = directory;
    }
    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }
    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }
    public void setTimestamp(boolean timestamp) {
        this.timestamp = timestamp;
    }
    //实现Logger接口-------------------------------------------------------------------------
    @Override
    public void log(String message) {
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        //格式: 2023-02-08 22:16:57
        String nowDateAndTime = timestamp.toString().substring(0, 19);
        //格式: 2023-02-08
        String nowDate = nowDateAndTime.substring(0, 10);
        //日期不一致,换文件写
        if (!date.equals(nowDate)) {
            synchronized (this) {
                if (!date.equals(nowDate)) {
                    close();
                    date = nowDate;
                    open();
                }
            }
        }
        if (writer != null) {
            //带时间打印
            if (this.timestamp) {
                writer.println(nowDateAndTime + " " + message);
            } else {
                writer.println(message);
            }
        }
    }

    //在指定目录下创建输出到指定文件的Writer(文件名为prefix + date + suffix)
    private void open() {
        File dir = new File(directory);
        //如果directory不是绝对路径,其相对路径为System.getProperty("server.base")
        if (!dir.isAbsolute()) {
            dir = new File(System.getProperty("server.base"), directory);
        }
        //创建目录及其父目录
        dir.mkdirs();
        try {
            //文件名
            String fileName = dir.getAbsolutePath() + File.separator + prefix + date + suffix;
            //追加模式,自动刷新
            writer = new PrintWriter(new FileWriter(fileName, true), true);
        } catch (IOException e) {
            writer = null;
        }

    }

    //关闭流
    private void close() {
        if (writer != null) {
            writer.flush();
            writer.close();
            writer = null;
            date = "";
        }
    }

    @Override
    public String getInfo() {
        return info;
    }

    //实现Lifecycle接口-------------------------------------------------------------------------
    @Override
    public void addLifecycleListener(LifecycleListener listener) {
        lifecycle.addLifecycleListener(listener);
    }

    @Override
    public LifecycleListener[] findLifecycleListeners() {
        return lifecycle.findLifecycleListeners();
    }

    @Override
    public void removeLifecycleListener(LifecycleListener listener) {
        lifecycle.removeLifecycleListener(listener);
    }

    @Override
    public void start() throws LifecycleException {
        if (started)
            throw new LifecycleException("File Logger has already been started");
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;
    }

    @Override
    public void stop() throws LifecycleException {
        if (!started)
            throw new LifecycleException("File Logger has not yet been started");
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
        close();
    }
}
